package com.kangjia.api.controller;

import java.io.IOException;
import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.kangjia.api.ReportApiImpl;
import com.kangjia.api.TokenApiImpl;
import com.kangjia.general.dao.query.Page;
import com.kangjia.general.dao.query.QueryParam;
import com.kangjia.jasckson.DataMapper;
import com.kangjia.model.m0.entity.User;
import com.kangjia.model.m0.entity.ViewStoreReport;
import com.kangjia.model.m0.service.ReportService;
import com.kangjia.model.m0.service.UserService;
import com.kangjia.response.PageResponse;

import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import lombok.extern.slf4j.Slf4j;

/**
 * 康加api请求控制器类
 * 
 * @author sunshulin
 *
 */
@Controller
@Slf4j
@RequestMapping(value = "/api")
public class KangjiaApiController extends AbstractApiController {

	@Autowired
	private TokenApiImpl tokenApiImpl;
	@Autowired
	private ReportApiImpl reportApiImpl;
	@Autowired
	private UserService userService;
	@Autowired
	private ReportService reportService;
	@Autowired
	private RabbitTemplate rabbitTemplate;
	
	@ApiOperation(value = "放入mq", notes = "获取康加接口访问token")
	@RequestMapping(value = "/full", method = RequestMethod.GET)
	@ResponseBody
	public PageResponse<ViewStoreReport> full() {
		Page page = new Page();
		QueryParam param = new QueryParam(page);
		List<ViewStoreReport> list = reportService.pager(ViewStoreReport.class, param);
		for (ViewStoreReport sr : list) {
			sendRabbitmq(sr.getInspectId());
		}
		return new PageResponse<>(param != null ? param.getTotal() : null, list);
	}
	
	/**
	 * 发送信息到mq中
	 * @param userId
	 * @param reportId
	 */
	private void sendRabbitmq(String reportId) {
		MessageProperties properties = new MessageProperties();
		Message message = new Message(reportId.getBytes(), properties);
		rabbitTemplate.send("*.report.*", message);
	}

	/**
	 * 康加token
	 * 
	 * @return
	 * @throws JsonProcessingException
	 * @throws IOException
	 */
	@ApiOperation(value = "康加接口访问token", notes = "获取康加接口访问token")
	@RequestMapping(value = "/getToken", method = RequestMethod.GET)
	@ResponseBody
	public String getToken() throws JsonProcessingException, IOException {
		log.info("获取token");
		tokenApiImpl.getToken();
		return "success";
	}

	/**
	 * 康加报告查询
	 * 
	 * @param userId
	 * @param reportId
	 * @param mobile
	 * @param name
	 * @param sex
	 * @return
	 * @throws JsonProcessingException
	 * @throws IOException
	 */
	@ApiOperation(value = "康加报告查询接口", notes = "康加报告查询接口")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "uid", value = "用户id", required = true, dataType = "String", paramType = "query"),
			@ApiImplicitParam(name = "reportId", value = "报告编号", required = true, dataType = "String", paramType = "query") })
	@RequestMapping(value = "/sendRequest", method = RequestMethod.GET)
	@ApiResponse(response = String.class, code = 200, message = "返回报告ID")
	@ResponseBody
	public String sendRequest(Long uid, String reportId) throws JsonProcessingException, IOException {
		log.info("发送报告请求");
		try {
			long s = System.currentTimeMillis();
			String reportData = reportApiImpl.getReport(reportId);
			if (StringUtils.isBlank(reportData)) {
				User user = userService.find(uid);
				if (user == null) {
					log.warn("用户不存在,uid={}", uid);
				}
				reportData = reportApiImpl.getReport(uid, reportId, user.getMobile(), user.getNickName(), getAge(user), user);
			} else {
				log.info("已存在报告={}", reportId);
			}
			set(reportId, reportData);
			log.info("耗时={}", System.currentTimeMillis() - s);
		} catch (Exception e) {
			log.error("获取报告异常,检测服务端接收.", e);
			return null;
		}
		log.info("结束报告解析");
		return reportId;
	}

	@ApiOperation(value = "康加报告查询回调接口", notes = "康加报告查询回调接口")
	@RequestMapping(value = "/callback", method = RequestMethod.POST)
	@ResponseBody
	public void callback(HttpServletRequest request, String uuid) throws JsonProcessingException, IOException {
		String json = getString(request);
		log.info("报告请求回调 json={}", json);
		JsonNode jsonNode = DataMapper.getInstance().readTree(json);
		JsonNode rep = jsonNode.get("repCode");
		if (rep.asInt() == 200) {
			reportApiImpl.handlerReport(jsonNode.get("data"), uuid);
		}
	}

	private String getString(HttpServletRequest request) {
		StringBuilder str = new StringBuilder();
		InputStream is = null;
		try {
			is = request.getInputStream();
			byte[] bytes = new byte[1024];
			while (is.read(bytes) != -1) {
				str.append(new String(bytes));
			}
		} catch (IOException e) {
			log.error("报告回调io异常", e);
		} finally {
			if (is != null) {
				try {
					is.close();
				} catch (IOException e) {
					log.error("inputstream关闭异常", e);
				}
			}
		}
		return str.toString();
	}

	private Integer getAge(User user) {
		if (StringUtils.isNotBlank(user.getBirth())) {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			Date birthDay = null;
			try {
				birthDay = sdf.parse(user.getBirth());
			} catch (ParseException e) {
				log.error("日期解析错误", e);
				return 0;
			}
			Calendar cal = Calendar.getInstance();
			if (cal.before(birthDay)) {
				throw new IllegalArgumentException("The birthDay is before Now.It's unbelievable!");
			}
			int yearNow = cal.get(Calendar.YEAR);
			int monthNow = cal.get(Calendar.MONTH);
			int dayOfMonthNow = cal.get(Calendar.DAY_OF_MONTH);
			cal.setTime(birthDay);

			int yearBirth = cal.get(Calendar.YEAR);
			int monthBirth = cal.get(Calendar.MONTH);
			int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);

			int age = yearNow - yearBirth;

			if (monthNow <= monthBirth) {
				if (monthNow == monthBirth) {
					if (dayOfMonthNow < dayOfMonthBirth)
						age--;
				} else {
					age--;
				}
			}
			return age;
		}

		return 0;
	}
}